package tr.richfacesext.components.texttoimg;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import tr.richfacesext.components.imgviewer.ImgViewerConstants;

/**
 * 
 * @author mert
 *
 */
public class TextToImgRenderer extends Renderer { 	

	Logger logger = LoggerFactory.getLogger(getClass());
	
	public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		TextToImg textToImg = (TextToImg) component;
		
		String value = (String) textToImg.getValue();
		BufferedImage bufferedImg = generateImgFromText(textToImg, value);
		putImgToSession(context, textToImg, bufferedImg);
		
		writer.startElement("span", textToImg);
		writer.startElement("img", textToImg);
		writer.writeAttribute("id", "img_" + textToImg.getId(), null);
		
		if (StringUtils.isNotEmpty(textToImg.getStyle())) {
			writer.writeAttribute("style", textToImg.getStyle(), null);
		}
			
		if (StringUtils.isNotEmpty(textToImg.getOnclick())) 
			writer.writeAttribute("onclick", textToImg.getOnclick(), null);
			
//		important for portals, where relative urls are assigned to portal layout url, not the project context
		String contextPath = context.getExternalContext().getRequestContextPath();
		writer.writeAttribute("src", contextPath + "/" + ImgViewerConstants.IMAGEVIEWER_VIEW_ID + "?" + ImgViewerConstants.KEYVAL_IMAGEID + "=" + getImageSessionKey(textToImg, bufferedImg), null);
		
		writer.endElement("img");
		writer.endElement("span");
	}
	
	private BufferedImage generateImgFromText(TextToImg textToImg, String text) {
		BufferedImage bufferedImg = new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = bufferedImg.createGraphics();
		
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
		                    RenderingHints.VALUE_ANTIALIAS_ON);
		
		int fontStyle = Font.PLAIN;
		if ("bold".equals(textToImg.getFontStyle()))
			fontStyle = Font.BOLD;
		if ("italic".equals(textToImg.getFontStyle()))
			fontStyle = Font.ITALIC;
		
		Font font = new Font(textToImg.getFontName(), fontStyle, textToImg.getFontSize());
		
		FontRenderContext fc = g2.getFontRenderContext();
		Rectangle2D bounds = font.getStringBounds(text,fc);

		// calculate the size of the text
		int width = (int) bounds.getWidth();
		int height = (int) bounds.getHeight();

		// prepare some output
		bufferedImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		g2 = bufferedImg.createGraphics();
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setFont(font);
		
		g2.setColor(Color.WHITE);
		g2.fillRect(0,0,width,height);
		g2.setColor(Color.BLACK);
		g2.drawString(text,0,(int)-bounds.getY());
		
		return bufferedImg;
	}
	
	
	@SuppressWarnings("unchecked")
	private void putImgToSession(FacesContext context, TextToImg textToImg, BufferedImage bufferedImage) {
		Object session = context.getExternalContext().getSession(true);
		
		if(bufferedImage==null)
			logger.warn("image is null!");
		
		if (session instanceof HttpSession){ 
			Map sessionMap = context.getExternalContext().getSessionMap();
			String sessionKey=getImageSessionKey(textToImg, bufferedImage);
			sessionMap.put(sessionKey, bufferedImage);
		}
		else{
			//portal context, variable must be put as Application scope to be accessed by phase listener
			String key=getImageSessionKey(textToImg, bufferedImage);

//			((PortletSession)session).setAttribute(key, bufferedImage, PortletSession.APPLICATION_SCOPE);
		}
	}
	
	private String getImageSessionKey(TextToImg textToImg, BufferedImage bufferedImage) {
		return bufferedImage.hashCode() + "_" + textToImg.getId();
	}
}